<template>
	<view class="chat-app-container">
		<!-- 聊天室列表界面 -->
		<view v-if="!currentRoomId" class="room-list">
			<view class="header">
				<text class="title">聊天室列表</text>
				<text class="fr" @click="back">返回</text>
			</view>
			<view class="room-item" @click="enterRoom('ROOM-8888')">
				<text class="room-name">聊天室 洛阳-同城群</text>
				<text class="room-status">{{ roomList['ROOM-8888']?.connected ? '在线' : '连接中...' }}</text>
			</view>
			<button class="join-room-btn" @click="enterRoom('ROOM-8888')">
				加入房间
			</button>
		</view>

		<!-- 聊天室内 对话框界面 element-ui 版本  -->
		<view v-if="currentRoomId">
			<!-- {{ messages }} -->
			<view class="messages-container">
				<view class="message-list" ref="messageList">
					<view v-for="(msg, index) in messages" :key="index" class="message"
						:class="{ 'own-message': msg.userId === userId, 'other-message': msg.userId !== userId }">
						<view class="message-avatar" :style="avatarBackground(msg.userId)">
							{{ generateAvatarInitial(msg.nickName) }}
						</view>
						<view class="message-content">
							<view class="message-header">
								<span class="message-user" v-if="msg.userId !== userId">{{ msg.nickName }}</span>
								<span class="message-user" v-else>我</span>
								<span class="message-time">{{ formatTime(msg.timestamp) }}</span>
								<text v-if="msg.userId === userId && !msg.revoked && isToday(msg.timestamp)" type="text"
									style="font-size: 12px; margin-left: 10px;" class="revoke-btn"
									@click="revokeMessage(msg.id)">
									撤回
								</text>
							</view>
							<view class="message-text">
								<template v-if="msg.revoked">已撤回</template>
								<template v-else-if="msg.text.includes('/upload/files/')">

									<image style="width:200px;  " mode="aspectFit" v-if="!msg.revoked"
										:src="`${baseUrl}${msg.text}`" :fit="fit" />
								</template>
								<template v-else>{{ msg.text }}</template>
							</view>
						</view>
					</view>

					<view v-if="messages.length === 0" class="empty-chat">
						<!-- <el-icon :size="60" color="#c0c4cc">
							<ChatLineSquare />
						</el-icon> -->
						<p style="margin-top: 15px;">当前房间还没有消息</p>
						<p style="font-size: 13px; margin-top: 10px;">开始发送第一条消息吧！</p>
					</view>
				</view>
				<view class="new-message-indicator" ref="newMessageIndicator" @click="scrollToBottom">新消息</view>
			</view>

			<view class="input-container">

				<view class="uni-textarea" style="position: relative;">
					<text class="test" @click=" showEmojiPicker=!showEmojiPicker">&#xe687;</text>
					<textarea class="chat-input" v-model="newMessage" placeholder-style="color:#999"
						@keyup.enter="sendMessage" placeholder="请输入聊天内容" />
				</view>
				<button type="primary" @click="sendMessage" style="padding: 5px 8px;">发送</button>
			</view>


			<view class="emoji-picker" v-show="showEmojiPicker">
				<view v-for="emoji in emojiList" :key="emoji" @click="insertEmoji(emoji)" class="emoji-item">
					{{ emoji }}
				</view>
			</view>

		</view>


	</view>
</template>

<script setup>
	import {
		ref,
		onMounted,
		onUnmounted,
		reactive,
		nextTick
	} from 'vue'

	import io from '@hyoga/uni-socket.io';
	import dayjs from 'dayjs';
	const currentRoomId = ref(null)
	// 状态变量
	const showRoomList = ref(true)
	const message = ref('')
	const room_users = ref([])
	const userId = ref(null)
 
	const messages = ref([])
	const roomList = reactive({
		'ROOM-8888': {
			connected: false,
			name: '聊天室 ROOM-8888'
		}
	})
	const messageList = ref() // 滚动dom
	const showEmojiPicker = ref(false)
	// 获取Token
	const getToken = () => {
		return uni.getStorageSync('token') || ''
	}
	const token = getToken()

	if (!token || token == '') {
		uni.showToast({
			title: '请先登录',
			icon: 'none'
		})
		uni.navigateTo({
			url: '/pages/chatroom/login'
		})
	}
	// 返回上一页
	const back = () => {
		uni.navigateBack()
	}


	const newMessage = ref('')

	const baseUrl = 'http://192.168.6.98:3000/v1'
	const headers = ref({
		Authorization: "Bearer " + getToken()
	});
	const uploadFileUrl = ref("http://192.168.6.98:3000/common/upload");
	const newMessageIndicator = ref(null)
	const autoScroll = ref(true)
	const emojiList = [
		'😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣', '😊', '😇',
		'🙂', '🙃', '😉', '😌', '😍', '🥰', '😘', '😗', '😙', '😚',
		'😋', '😛', '😝', '😜', '🤪', '🤨', '🧐', '🤓', '😎', '🥳'
	]

	// 头像颜色方案
	const avatarColors = [
		'#FF6B6B', '#4ECDC4', '#FFA62B', '#9C89B8',
		'#5E60CE', '#80FFDB', '#F72585', '#90BE6D',
		'#FF6D6D', '#67D5B5', '#FFB11B', '#B56BFF',
		'#2A9D8F', '#E9C46A', '#FF5D73', '#5DA9E9'
	]


	const socket = io('http://192.168.6.98:3000', {
		auth: {
			token: "Bearer " + getToken()
		}
	})

	// 加入房间
	const enterRoom = (roomId) => {
		if (!roomId) {

			return
		}

		if (!token || token == '') {
			uni.navigateTo({
				url: '/pages/chatroom/index'
			})
		}
		currentRoomId.value = roomId
		// 重置消息列表
		messages.value = []

		// 加入房间
		socket.emit('join_room', roomId)
		roomList[roomId].connected = true
		// 设置当前房间

	}
	socket.on('connect', () => {
		console.log('Connected to server');
	});




	// 进入聊天室
	onMounted(() => {
		// 添加滚动监听
		const container = document.querySelector('.messages-container')
		if (container) {
			container.addEventListener('scroll', handleScroll)
		}

		// 初始滚动到底部
		scrollToBottom()

		// 分配用户ID
		socket.on('assign_id', (assignedUserId) => {
			userId.value = assignedUserId

		})

		// 系统消息（用户加入/离开）
		socket.on('user_joined', ({
			userId,
			nickName
		}) => {
			receiveMessage({
				userId: '系统通知',
				nickName: '系统通知',
				text: `${nickName} 已加入房间`,
				timestamp: new Date()
			})
		})

		socket.on('user_left', ({
			userId,
			nickName
		}) => {
			receiveMessage({
				userId: '系统通知',
				nickName: '系统通知',
				text: `${nickName} 已离开房间`,
				timestamp: new Date()
			})
		})

		// 聊天消息
		socket.on('new_message', (msg) => {
			receiveMessage(msg)
		})


		// 监听消息撤回事件
		socket.on('message_revoked', (data) => {
			const messageIndex = messages.value.findIndex(msg => msg.id === data.messageId);
			if (messageIndex !== -1) {
				messages.value[messageIndex].revoked = true;
			}
		});



		// 房间用户列表
		socket.on('room_users', (data) => {
			console.log('当前房间用户:', data.users)
			//   data.users 中如果 userId 相同，则数组去重
			room_users.value = data.users.filter((item, index, arr) => {

				return arr.findIndex(i => i.userId === item.userId) === index

			})
			// 这里可以展示房间内的活跃用户
		})

		// 历史消息
		socket.on('room_history', ({
			roomId,
			historyMessages
		}) => {
			console.log('历史消息:', roomId, historyMessages)
			messages.value = historyMessages
			scrollToBottom()
			uni.showToast({
				title: `已加载 ${historyMessages.length} 条历史消息`,
				icon: 'none'
			})
		})

		// 错误处理
		socket.on('error', (error) => {
			 uni.showToast({
				title: '连接错误',
				icon: 'none'
			})
		})

		// 身份验证失败
		socket.on('connect_error', (error) => {
			if (error.data && error.data.type === '身份验证失败') {
			 
				 uni.showToast({
				title: '身份验证失效，请重新登录',
				icon: 'none'
			})
				router.push('/login')
			} else {
				uni.showToast({
				title: `连接错误: ${error.message}`,
				icon: 'none'
			})
			}
		})



		// 未授权访问
		socket.on('unauthorized', (error) => {
			uni.showToast({
				title: '需要登录后才能加入聊天室',
				icon: 'none'
			})
		})
	})
	// 接收消息处理
	const receiveMessage = (msg) => {
		messages.value.push({
			...msg,
			revoked: false
		}) // 添加撤回标记状态
		scrollToBottom()
	}

	// 滚动到底部
	const scrollToBottom = () => {
		nextTick(() => {
			const container = document.querySelector('.message-list')
			if (container) {
				container.scrollTop = container.scrollHeight
			}
			// if (newMessageIndicator.value) {
			// 	newMessageIndicator.value.style.display = 'none'
			// }
		})
	}

	const sendMessage = () => {
		if (!newMessage.value.trim() || !currentRoomId.value) return

		const text = newMessage.value.trim()
		newMessage.value = ''

		// 通过socket发送消息
		socket.emit('send_message', {
			roomId: currentRoomId.value,
			text: text
		})
		scrollToBottom()
	}

	// 添加撤回消息方法
	const revokeMessage = (messageId) => {
		const messageIndex = messages.value.findIndex(msg => msg.id === messageId);
		if (!messageIndex) return;

		// 发送撤回请求到服务器
		socket.emit('revoke_message', {
			roomId: currentRoomId.value,
			messageId: messageId,
		});

		// 前端临时更新状态，等待服务器确认
		messages.value[messageIndex].revoked = true;

	}


	function isToday(datetime) {
		console.log('dayjs', dayjs(datetime).format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD'))
		return dayjs(datetime).format('YYYY-MM-DD') === dayjs().format('YYYY-MM-DD')
	}
	// 时间格式化
	const formatTime = (date) => {
		// 日期需要把 mm-dd 带上，不用带年

		const d = new Date(date)
		return `${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')} 
		${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}

		`

	}

	const avatarBackground = (userId) => {
		// 强制转换为字符串处理
		const userIdStr = userId.toString();

		// 使用更标准的哈希算法
		let hash = 0;
		for (let i = 0; i < userIdStr.length; i++) {
			const charCode = userIdStr.charCodeAt(i); // 获取当前字符的 Unicode 编码
			hash = charCode + ((hash << 5) - hash); // 更合理的哈希计算
		}

		// 确保正整数
		hash = Math.abs(hash);


		// 计算颜色索引
		const colorIndex = hash % avatarColors.length;
		console.log(hash, 'hash', colorIndex, '颜色索引', avatarColors[colorIndex]);

		return {
			backgroundColor: avatarColors[colorIndex]
		};
	}

	// 生成头像首字母
	const generateAvatarInitial = (nickName) => {
		// 系统消息使用特殊标志
		if (!nickName || typeof nickName !== 'string') {
			return 'U'; // 默认返回 'U' 表示未知用户
		}
		if (nickName === '系统通知') return '系'
		//  nickName = 截取汉字的第一个字符
		return nickName.charAt(0)
	}

	// 插入表情到光标位置
	const insertEmoji = (emoji) => {
		const input = document.querySelector('.chat-input textarea')
		if (!input) return

		const startPos = input.selectionStart
		const endPos = input.selectionEnd

		newMessage.value = newMessage.value.substring(0, startPos) +
			emoji +
			newMessage.value.substring(endPos)

		// 恢复光标位置
		nextTick(() => {
			input.selectionStart = input.selectionEnd = startPos + emoji.length
		})


	}
</script>
<style lang="scss">
	@import url(../../static/uni.scss);
</style>
<style scoped>
	@font-face {
		font-family: 'iconfont';
		src: url('https://at.alicdn.com/t/font_865816_17gjspmmrkti.ttf') format('truetype');
	}

	.test {
		font-family: iconfont;
		margin-left: 20rpx;
		position: absolute;
		right: 5px;
		top: 5px;
		z-index: 99;
	}

	.chat-app-container {
		display: flex;
		flex-direction: column;
		height: 100vh;
		background-color: #f5f5f5;
	}

	/* 聊天室列表样式 */
	.room-list {
		padding: 20rpx;
	}

	.header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 20rpx 0;
		border-bottom: 1rpx solid #eee;
	}

	.title {
		font-size: 40rpx;
		font-weight: bold;
		color: #333;
	}

	.back-btn {
		background-color: #fff;
		color: #666;
		border: 1rpx solid #ddd;
		padding: 10rpx 20rpx;
		font-size: 28rpx;
	}

	.room-item {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 30rpx 20rpx;
		margin-top: 20rpx;
		background-color: #fff;
		border-radius: 10rpx;
		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
	}

	.room-name {
		font-size: 32rpx;
		color: #333;
	}

	.room-status {
		font-size: 28rpx;
		color: #07c160;
	}

	.join-room-btn {
		width: 100%;
		height: 80rpx;
		background-color: #07c160;
		color: #fff;
		font-size: 32rpx;
		border-radius: 10rpx;
		margin-top: 30rpx;
		line-height: 80rpx;
	}

	.join-room-dialog {
		padding: 30rpx;
		background-color: #fff;
		border-radius: 10rpx;
		width: 80%;
		margin: 0 auto;
	}

	.dialog-title {
		display: block;
		font-size: 36rpx;
		font-weight: bold;
		color: #333;
		margin-bottom: 30rpx;
		text-align: center;
	}

	.join-room-input {
		width: 100%;
		height: 80rpx;
		background-color: #f5f5f5;
		border-radius: 10rpx;
		padding: 0 20rpx;
		font-size: 32rpx;
		margin-bottom: 30rpx;
	}

	.dialog-buttons {
		display: flex;
		justify-content: space-between;
	}

	.cancel-btn {
		flex: 1;
		height: 80rpx;
		background-color: #f5f5f5;
		color: #666;
		font-size: 32rpx;
		border-radius: 10rpx;
		margin-right: 20rpx;
		line-height: 80rpx;
	}

	.confirm-btn {
		flex: 1;
		height: 80rpx;
		background-color: #07c160;
		color: #fff;
		font-size: 32rpx;
		border-radius: 10rpx;
		line-height: 80rpx;
	}

	.fr {
		float: right;
	}
</style>